package com.ewing.busi.order.service;

import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.Validate;
import org.springframework.stereotype.Repository;

import com.ewing.busi.customer.dto.AddressDetailResp;
import com.ewing.busi.customer.dto.LightAddressInfoResp;
import com.ewing.busi.customer.service.CustomerAddressService;
import com.ewing.busi.order.constants.OrderStatus;
import com.ewing.busi.order.constants.PayType;
import com.ewing.busi.order.dao.OrderInfoDao;
import com.ewing.busi.order.dto.AddOrdeReq;
import com.ewing.busi.order.dto.CommitOrdeReq;
import com.ewing.busi.order.dto.ConfirmOrderReq;
import com.ewing.busi.order.dto.ConfirmOrderReq.Item;
import com.ewing.busi.order.dto.LightOrderInfoResp;
import com.ewing.busi.order.dto.OrderInfoDetailResp;
import com.ewing.busi.order.helper.OrderHelper;
import com.ewing.busi.order.model.OrderDetail;
import com.ewing.busi.order.model.OrderInfo;
import com.ewing.busi.pay.dao.PayHistoryDao;
import com.ewing.busi.resource.dao.WebResourceDao;
import com.ewing.busi.resource.model.WebResource;
import com.ewing.busi.resource.model.WebResourcePrice;
import com.ewing.busi.resource.service.WebResourceService;
import com.ewing.busi.seller.service.SellerShopService;
import com.ewing.busi.web.mgr.WebResourceMgr;
import com.ewing.common.constants.AjaxRespCode;
import com.ewing.common.constants.IsEff;
import com.ewing.common.constants.ResponseCode;
import com.ewing.common.exception.BusinessException;
import com.ewing.core.jdbc.BaseDao;
import com.ewing.utils.BizGenerator;
import com.ewing.utils.IntegerUtils;
import com.google.common.collect.Lists;

@Repository("orderInfoService")
public class OrderInfoService {

  @Resource
  private WebResourceMgr webResourceMgr;
  @Resource
  private BaseDao baseDao;
  @Resource
  private OrderInfoDao orderInfoDao;

  @Resource
  private OrderDetailService orderDetailService;

  @Resource
  private WebResourceService webResourceService;
  @Resource
  private WebResourceDao webResoueceDao;
  @Resource
  private CustomerAddressService customerAddressService;
  @Resource
  private OrderProcessHistoryService orderProcessHistoryService;
  @Resource
  private PayHistoryDao payHistoryDao;
  @Resource
  private SellerShopService sellerShopService;

  /**
   * 根据客户id查询 购物车列表
   * 
   * @param cusId 客户ID
   * @param statusList 订单状态
   */
  public List<LightOrderInfoResp> queryByCusId(Integer cusId, Integer shopId, List<String> statusList, Integer page,
      Integer pageSize) {
    Validate.notNull(cusId, "客户id不能为空");
    Validate.notNull(page, "page不能为空");
    Validate.notNull(pageSize, "pageSize不能为空");

    List<LightOrderInfoResp> dtoList = Lists.newArrayList();
    List<OrderInfo> orderList =
        orderInfoDao.queryByCusIdAndStatus(cusId, statusList, page, pageSize);
    for (OrderInfo order : orderList) {
      List<OrderInfoDetailResp> detailDtoList =
          orderDetailService.findByOrderIdAndCusId(order.getId(), cusId, shopId);
      if (CollectionUtils.isEmpty(detailDtoList)) {
        continue;
      }

      dtoList.add(new LightOrderInfoResp(order, detailDtoList));
    }

    return dtoList;
  }

//  /**
//   * 查询订单详情
//   * 
//   * @param cusId 客户ID
//   * @param orderId order_info的id
//   * @param pageSize 
//   * @param page 
//   * @param list 
//   */
//  public LightOrderInfoResp queryByCusId(Integer cusId, Integer orderId, List<String> list, Integer page, Integer pageSize) {
//    Validate.notNull(cusId, "客户id不能为空");
//
//    OrderInfo order = orderInfoDao.findByIdAndCusId(cusId, orderId);
//    if (null == order) {
//      return null;
//    }
//
//    List<OrderInfoDetailResp> detailDtoList =
//        orderDetailService.findByOrderIdAndCusId(order.getId(), cusId);
//    return new LightOrderInfoResp(order, detailDtoList);
//  }

  /**
   * 确认订单
   * 
   * @param req
   * @author Joeson
   */
  public void confirmOrder(ConfirmOrderReq req) {
    Validate.notNull(req, "入参不能为空");

    Integer orderId = null;
    float totalPrice = 0f;
    float catgoPrice = 0f;
    for (Item item : req.getList()) {
      OrderDetail detail = baseDao.findOne(item.getDetailId(), OrderDetail.class);
      detail.setItemCount(item.getItemCount());
      detail.setStatus(OrderStatus.WAIT_PAY.getValue());
      detail.setTotalPrice(OrderHelper.analysyTotal(detail));
      totalPrice = totalPrice + detail.getTotalPrice();

      orderId = detail.getOrderId();
      baseDao.update(detail);

      // 运费，去所有订单项中最大的一个 @FIXME后期可能改成具体的取运费策略
      catgoPrice = catgoPrice < detail.getCargoPrice() ? detail.getCargoPrice() : catgoPrice;
    }

    OrderInfo order = baseDao.findOne(orderId, OrderInfo.class);
    order.setTotalPrice(totalPrice);
    order.setCargoPrice(catgoPrice);
    order.setStatus(OrderStatus.WAIT_PAY.getValue());
    baseDao.update(order);

    // 记录流程记录
    orderProcessHistoryService.addOrderHistory(order, OrderStatus.WAIT_PAY);
  }

  /**
   * 取消order,如果order为已付款、待收货，不能关闭订单
   * 
   * @param orderId
   * @author Joeson
   * @param orderId
   */
  public void closeOrder(Integer cusId, Integer orderId) {
    Validate.notNull(orderId, "orderId不能为空");

    OrderInfo order = baseDao.findOne(orderId, OrderInfo.class);
    Validate.notNull(order, "order不能为空");

    if (!IntegerUtils.equals(order.getCustomerId(), cusId)) {
      return;
    }
    // 如果状态不为待付款或已收货，不能关闭订单
    if (!(ObjectUtils.equals(order.getStatus(), OrderStatus.WAIT_PAY.getValue())
        || ObjectUtils.equals(order.getStatus(), OrderStatus.FINISHED.getValue()))) {
      throw new BusinessException(ResponseCode.BIZ_STATUS_ERROR, "当前状态不能关闭订单");
    }

    order.setStatus(OrderStatus.CLOSED.getValue());
    baseDao.update(order);

    // 记录流程记录
    orderProcessHistoryService.addOrderHistory(order, OrderStatus.CLOSED);

    return;
  }

  /**
   * 添加到order，场景：立即订购 如果priceId为空，则取web_resource中的price
   * 
   * @param cusId 客户id
   * @param req 请求参数
   * @author Joeson
   * @throws Exception
   */
  public Integer addOrder(Integer cusId, AddOrdeReq req) throws Exception {
    Validate.notNull(req, "入参不能为空");
    Validate.notNull(req.getResourceId(), "resourceId不能为空");
    Validate.notNull(req.getCount(), "count不能为空");

    Integer resourceId = req.getResourceId();
    Integer priceId = req.getPriceId();
    Integer count = req.getCount();

    WebResource resource = baseDao.findOne(resourceId, WebResource.class);
    Validate.notNull(resource, String.format("没有找到对应的资源[id=%d]", resourceId));

    WebResourcePrice price =
        null == priceId ? null : baseDao.findOne(priceId, WebResourcePrice.class);

    String bizId = BizGenerator.generateBizNum();
    // 保存orderinfo
    OrderInfo orderInfo = new OrderInfo();
    orderInfo.setCustomerId(cusId);
    orderInfo.setUserId(resource.getUserId());
    orderInfo.setBizId(bizId);
    orderInfo.setCargoPrice(0f);
    orderInfo.setTotalPrice(0f);
    orderInfo.setStatus(OrderStatus.INIT.getValue());
    orderInfo.setIseff(IsEff.EFFECTIVE.getValue());
    baseDao.save(orderInfo);

    OrderDetail detail = OrderHelper.initOrderDetail(orderInfo.getId(), priceId, cusId, bizId,
        count, resource, price);
    baseDao.save(detail);

    // 保存orderinfo的总价还有运费
    orderInfo.setTotalPrice(OrderHelper.analysyTotal(detail));
    orderInfo.setCargoPrice(detail.getCargoPrice());
    baseDao.update(orderInfo);

    return orderInfo.getId();
  }

  /**
   * @TODO 这个方法后面要加事务 提交订单，将订单状态改为待支付状态 <br/>
   *       这一步必须保证地址不能为空
   * 
   * @param cusId
   * @param req
   * @author Joeson
   */
  public boolean commitOrder(Integer cusId, CommitOrdeReq req) {
    Validate.notNull(cusId, "cusId不能为空");
    Validate.notNull(req, "req不能为空");
    Validate.notNull(req.getAddrId(), "addrId不能为空");

    AddressDetailResp address = customerAddressService.findById(req.getAddrId(), cusId);
    Validate.notNull(address, String.format("地址为空[addrId=%d]", req.getAddrId()));
    List<com.ewing.busi.order.dto.CommitOrdeReq.Item> list = req.getList();
    List<Integer> detailIdList = Lists.newArrayList();

    for (com.ewing.busi.order.dto.CommitOrdeReq.Item item : list) {
      detailIdList.add(item.getDetailId());
    }
    List<OrderDetail> detailList = baseDao.findMuti(detailIdList, OrderDetail.class);

    List<Integer> orderInfoIdList = Lists.newArrayList();// 一般是同一次提交只有一个orderinfo的
    for (OrderDetail detail : detailList) {
      orderInfoIdList.add(detail.getOrderId());
    }
    List<OrderInfo> orderList = baseDao.findMuti(orderInfoIdList, OrderInfo.class);
    if (CollectionUtils.isEmpty(orderList)) {
      return false;
    }
    OrderInfo order = orderList.get(0);
    if (ObjectUtils.equals(order.getStatus(), OrderStatus.WAIT_PAY.getValue())) {// 如果代支付，直接返回true，页面调用微信jspay
      return true;
    }
    if (!ObjectUtils.equals(order.getStatus(), OrderStatus.INIT.getValue())) {
      throw new BusinessException(AjaxRespCode.ORDER_INVALID_STATE.code,
          "当前订单状态为" + OrderStatus.getMsg(order.getStatus()));
    }

    float totalPrice = req.getCarryPrice();
    // 更新操作
    for (OrderDetail detail : detailList) {
      detail.setTotalPrice(OrderHelper.analysyTotal(detail));
      totalPrice = totalPrice + detail.getTotalPrice();

      detail.setStatus(OrderStatus.WAIT_PAY.getValue());
      baseDao.update(detail);

    }

    order.setStatus(OrderStatus.WAIT_PAY.getValue());
    order.setPayWay(PayType.PAY_ONLINE.getValue());
    order.setPhone(address.getPhone());
    order.setProvince(address.getProvince());
    order.setCity(address.getCity());
    order.setRegion(address.getRegion());
    order.setAddress(address.getAddress());
    order.setReceiver(address.getReceiver());
    order.setTotalPrice(totalPrice);
    order.setCargoPrice(req.getCarryPrice());
    order.setCargoWay(req.getCarryWay());

    // 记录流程记录
    orderProcessHistoryService.addOrderHistory(order, OrderStatus.WAIT_PAY);
    baseDao.update(order);

    return true;
  }

  /**
   * 获取订单地址
   * 
   * @author Joeson
   */
  public LightAddressInfoResp getOrderAddress(Integer orderId, Integer cusId) {
    Validate.notNull(orderId, "orderId不能为空");

    OrderInfo order = baseDao.findOne(orderId, OrderInfo.class);
    Validate.notNull(order, String.format("找不到order[orderId=%d]", orderId));

    return OrderHelper.toAddress(order);
  }

  /**
   * 获取支付方式
   * 
   * @param orderId
   * @param cusId
   * @author Joeson
   */
  public com.ewing.busi.resource.helper.PayWayHelper.Item getPayWay(Integer orderId,
      Integer cusId) {
    Validate.notNull(orderId, "orderId不能为空");

    OrderInfo order = baseDao.findOne(orderId, OrderInfo.class);
    Validate.notNull(order, String.format("找不到order[orderId=%d]", orderId));

    return OrderHelper.toPayWay(order);
  }

  public OrderInfo findByIdAndCusId(int id, int cusId) {
    return orderInfoDao.findByIdAndCusId(id, cusId);
  }


}
